package per.jdz.demo.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import lombok.extern.slf4j.Slf4j;
import per.jdz.demo.readlistener.GenericReadListener;
import per.jdz.demo.readlistener.WriteListener;

import java.io.File;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

/**
 * @author Jdz
 * @date 2025/2/5
 */
@Slf4j
public class FileUtil {
    public static boolean deleteDirectory(File directory) {
        if (directory.isDirectory()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (!deleteDirectory(file)) {
                        return false;
                    }
                }
            }
        }
        return directory.delete();
    }

    public static String splitFile(String originFileDir, String originSplit, Class<?> clazz) {
        final File fileObj = new File(originFileDir);
        final File splitObj = new File(originSplit);
        String msg = "处理成功";
        if (!fileObj.exists()) {
            msg = originFileDir + "不存在";
            log.warn("{}不存在", originFileDir);
            return msg;
        }
        if (splitObj.exists()) {
            boolean delete = FileUtil.deleteDirectory(splitObj);
            if (!delete) {
                log.error("split文件夹删除失败");
                msg = "split文件夹删除失败";
                return msg;
            }
        }
        boolean mkdir = splitObj.mkdir();
        if (!mkdir) {
            log.error("文件夹创建失败");
            msg = "split文件夹创建失败";
            return msg;
        }
        CompletableFuture.allOf(Arrays.stream(Objects.requireNonNull(fileObj.listFiles()))
                .map(file -> CompletableFuture.runAsync(() -> {
                    log.info("开始读取文件: {}", file.getName());
                    processWriteFile(file, clazz, originSplit);
                })).toArray(CompletableFuture[]::new)).join();
        return msg;
    }

    private static void processWriteFile(File file, Class<?> clazz, String originSplit) {
        if (file.isDirectory()) return;
        final File splitObj = new File(originSplit);
        String fileName = file.getName();
        String prefix;
        try {
            prefix = fileName.substring(0, fileName.lastIndexOf("."));
            if (fileName.endsWith(ExcelTypeEnum.CSV.getValue())) {
                EasyExcel.read(file, clazz, new WriteListener<>(prefix, ExcelTypeEnum.CSV.getValue(), splitObj.getAbsolutePath()))
                        .excelType(ExcelTypeEnum.CSV)
                        .sheet()
                        .doRead();
            } else if (fileName.endsWith(ExcelTypeEnum.XLSX.getValue())) {
                EasyExcel.read(file, clazz, new WriteListener<>(prefix, ExcelTypeEnum.XLSX.getValue(), splitObj.getAbsolutePath()))
                        .excelType(ExcelTypeEnum.XLSX)
                        .sheet()
                        .doRead();
            } else {
                log.error("不支持的文件类型: {}", fileName);
                return;
            }

            log.info("成功处理文件: {}", fileName);
        } catch (Exception e) {
            log.error("处理文件 {} 时发生错误: {}", fileName, e.getMessage(), e);
        }
    }

    public static void insertData(String originSplitDir, Class<?> clazz, GenericReadListener.BatchProcessor batchProcessor) {
        final File splitObj = new File(originSplitDir);
        CompletableFuture.allOf(Arrays.stream(Objects.requireNonNull(splitObj.listFiles()))
                .map(file -> CompletableFuture.runAsync(() -> {
                    log.info("开始读取文件: {}", file.getName());
                    processFile(file, clazz, batchProcessor);
                })).toArray(CompletableFuture[]::new)).join();
    }

    private static void processFile(File file,  Class<?> clazz, GenericReadListener.BatchProcessor batchProcessor) {
        if (file.isDirectory()) return;
        String fileName = file.getName();
        if (fileName.endsWith(ExcelTypeEnum.CSV.getValue())) {
            EasyExcel.read(file, clazz, new GenericReadListener<>(fileName, null, batchProcessor)).excelType(ExcelTypeEnum.CSV).sheet().doRead();
        } else if (fileName.endsWith(ExcelTypeEnum.XLSX.getValue())) {
            EasyExcel.read(file, clazz, new GenericReadListener<>(fileName, null, batchProcessor)).excelType(ExcelTypeEnum.XLSX).sheet().doRead();
        } else {
            log.error("文件类型不支持{}", fileName);
        }
    }
}
